import { toLatLng } from "../geometry/LatLng";



export default class CoorsOffset {
  constructor() {
    this.x_pi = (3.14159265358979324 * 3000.0) / 180.0;
    this.pi = 3.14159265358979324;
    this.a = 6378245.0;
    this.ee = 0.00669342162296594323;
  }

  /**
   * GCJ02 转换为 WGS84
   * @param lng
   * @param lat
   * @returns {*[longitude, latitude]}
   */
  gcj02towgs84(lng, lat) {

    var dlat = this.transformlat(lng - 105.0, lat - 35.0);
    var dlng = this.transformlng(lng - 105.0, lat - 35.0);
    const radlat = (lat / 180.0) * this.pi;
    const magic = 1 - this.ee * Math.sin(radlat) * Math.sin(radlat);
    const sqrtmagic = Math.sqrt(magic);

    dlat =
      (dlat * 180.0) /
      (((this.a * (1 - this.ee)) / (magic * sqrtmagic)) * this.pi);
    dlng = (dlng * 180.0) / ((this.a / sqrtmagic) * Math.cos(radlat) * this.pi);

    const mglat = lat + dlat;
    const mglng = lng + dlng;
    return toLatLng(lng * 2 - mglng, lat * 2 - mglat);
  }

  /**
   * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
   * 即 百度 转 谷歌、高德
   * @param {*} DBLon
   * @param {*} DBLat
   * @returns {*[longitude, latitude]}
   */
  bd09togcj02 = (DBLon, DBLat) => {
    const x = DBLon - 0.0065;
    const y = DBLat - 0.006;
    const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * this.x_pi);
    const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * this.x_pi);
    const lon = z * Math.cos(theta);
    const lat = z * Math.sin(theta);

    return [lon, lat];
  };

  /**
   * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
   * 即谷歌、高德 转 百度
   * @param lng
   * @param lat
   * @returns {*[longitude, latitude]}
   */
  gcj02tobd09 = (lng, lat) => {
    const z =
      Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * this.x_pi);
    const theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * this.x_pi);
    const BDLng = z * Math.cos(theta) + 0.0065;
    const DBLat = z * Math.sin(theta) + 0.006;

    return toLatLng(BDLng, DBLat);
  };

  /**
   * WGS84转GCj02
   * @param lng
   * @param lat
   * @returns {*[longitude, latitude]}
   */
  wgs84togcj02 = (lng, lat) => {
    const radlat = (lat / 180.0) * this.pi;
    const magic = 1 - this.ee * Math.sin(radlat) * Math.sin(radlat);
    const sqrtmagic = Math.sqrt(magic);

    let dlat = this.transformlat(lng - 105.0, lat - 35.0);

    let dlng = this.transformlng(lng - 105.0, lat - 35.0);

    dlat =
      (dlat * 180.0) /
      (((this.a * (1 - this.ee)) / (magic * sqrtmagic)) * this.pi);
    dlng = (dlng * 180.0) / ((this.a / sqrtmagic) * Math.cos(radlat) * this.pi);
    let mglat = lat + dlat;

    let mglng = lng + dlng;

    return toLatLng(mglng, mglat);
  };

  transformlat = (lng, lat) => {
    let ret =
      -100.0 +
      2.0 * lng +
      3.0 * lat +
      0.2 * lat * lat +
      0.1 * lng * lat +
      0.2 * Math.sqrt(Math.abs(lng));

    ret +=
      (20.0 * Math.sin(6.0 * lng * this.pi) +
        20.0 * Math.sin(2.0 * lng * this.pi)) *
      (2.0 / 3.0);
    ret +=
      (20.0 * Math.sin(lat * this.pi) +
        40.0 * Math.sin((lat / 3.0) * this.pi)) *
      (2.0 / 3.0);
    ret +=
      (160.0 * Math.sin((lat / 12.0) * this.pi) +
        320 * Math.sin((lat * this.pi) / 30.0)) *
      (2.0 / 3.0);

    return ret;
  };

  transformlng = (lng, lat) => {
    let ret =
      300.0 +
      lng +
      2.0 * lat +
      0.1 * lng * lng +
      0.1 * lng * lat +
      0.1 * Math.sqrt(Math.abs(lng));

    ret +=
      (20.0 * Math.sin(6.0 * lng * this.pi) +
        20.0 * Math.sin(2.0 * lng * this.pi)) *
      (2.0 / 3.0);
    ret +=
      (20.0 * Math.sin(lng * this.pi) +
        40.0 * Math.sin((lng / 3.0) * this.pi)) *
      (2.0 / 3.0);
    ret +=
      (150.0 * Math.sin((lng / 12.0) * this.pi) +
        300.0 * Math.sin((lng / 30.0) * this.pi)) *
      (2.0 / 3.0);

    return ret;
  };
}

export const toCoorsOffset = () => {
   return new CoorsOffset()
}
 export const coorsOffset = () => {
   return new CoorsOffset();
 };